/*
 * Copyright (c) 2003, 2004 Ulrich Hilger, http://dev.uhilger.de, all rights reserved.
 *
 * Published under the terms and conditions of the Apache License 2.0,
 * see http://www.apache.org/licenses/LICENSE-2.0
 */

package de.uhilger.app.ui;

import java.awt.event.ActionListener;
import java.awt.AWTEvent;
import java.awt.event.WindowEvent;
import java.awt.event.ActionEvent;
import javax.swing.JDialog;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.Frame;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Container;
import java.awt.Dialog;
import javax.help.*;
import de.uhilger.app.Application;
import java.awt.Dimension;
import java.awt.Component;
import java.awt.Point;

/**
 * Base class for other dialogs of application AlbumHelper.
 *
 * @author Ulrich Hilger, <a href="http://dev.uhilger.de" target="_blank">http://dev.uhilger.de</a>
 * @author Published under the terms and conditions of
 * the <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License 2.0</a>
 *
 * @version 1, February 8, 2004
 */

public class DialogShell extends JDialog implements ActionListener {

  /** panel containing dialog buttons */
  protected JPanel buttonPanel;

  /** button to confirm the operation */
  protected JButton okButton;

  /** button to cancel the operation */
  protected JButton cancelButton;

  /** button to display context sensitive help */
  protected JButton helpButton;

  /**
   * the result of the operation, one of RESULT_CANCEL and RESULT_OK
   */
  private int result;

  /** result value for a cancelled operation */
  public static int RESULT_CANCEL = 1;

  /** result value for a confirmed operation */
  public static int RESULT_OK = 0;

  /** id of associated help topic (if any) */
  protected String helpTopicId = null;

  private HelpBroker myHelpBroker;

  /**
   * constructor
   *
   * @param parent  the parent dialog
   * @param title  the title for this dialog
   */
  public DialogShell(Application app, Dialog parent, String title) {
    super(parent, title);
    buildDialog(app);
  }

  /**
   * constructor
   *
   * @param parent  the parent frame
   * @param title  the title for this dialog
   */
  public DialogShell(Application app, Frame parent, String title) {
    super(parent, title);
    buildDialog(app);
  }

  /**
   * constructor
   *
   * @param parent  the parent frame
   * @param title  the title for this dialog
   * @param helpTopicId  the id of the help topic to display for this dialog
   */
  public DialogShell(Application app, Frame parent, String title, String helpTopicId) {
    super(parent, title);
    this.helpTopicId = helpTopicId;
    buildDialog(app);
  }

  /**
   * constructor
   *
   * @param parent  the parent dialog
   * @param title  the title for this dialog
   * @param helpTopicId  the id of the help topic to display for this dialog
   */
  public DialogShell(Application app, Dialog parent, String title, String helpTopicId) {
    super(parent, title);
    this.helpTopicId = helpTopicId;
    buildDialog(app);
  }

  /**
   * constructor
   *
   * @param parent  the parent dialog
   * @param title  the title for this dialog
   * @param helpTopicId  the id of the help topic to display for this dialog
   * @param broker  the helpBroker to use for context sensitive help
   */
  public DialogShell(Application app, Dialog parent, String title, String helpTopicId, HelpBroker broker) {
    super(parent, title);
    this.helpTopicId = helpTopicId;
    this.myHelpBroker = broker;
    buildDialog(app);
  }

  /**
   * constructor
   *
   * @param parent  the parent dialog
   * @param title  the title for this dialog
   * @param helpTopicId  the id of the help topic to display for this dialog
   * @param broker  the helpBroker to use for context sensitive help
   */
  public DialogShell(Application app, Frame parent, String title, String helpTopicId, HelpBroker broker) {
    super(parent, title);
    this.helpTopicId = helpTopicId;
    this.myHelpBroker = broker;
    buildDialog(app);
  }

  /**
   * create dialog components
   */
  private void buildDialog(Application app) {
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);

    // construct dialog buttons
    okButton = new JButton(app.getResourceString("okBtnName"));
    cancelButton = new JButton(app.getResourceString("cancelBtnName"));
    cancelButton.addActionListener(this);
    okButton.addActionListener(this);

    // construct button panel
    buttonPanel = new JPanel(new FlowLayout());
    buttonPanel.add(okButton);
    buttonPanel.add(cancelButton);

    // construct help button
    if(helpTopicId != null) {
      helpButton = new JButton(app.getResourceString("helpLabel"));
      CSH.setHelpIDString(helpButton, helpTopicId);
      if(myHelpBroker == null) {
        if(myHelpBroker != null) {
          helpButton.addActionListener(
              new CSH.DisplayHelpFromSource(myHelpBroker));
        }
        else {
          helpButton.setEnabled(false);
        }
      }
      else {
        helpButton.addActionListener(
            new CSH.DisplayHelpFromSource(myHelpBroker));
      }
      buttonPanel.add(helpButton);
    }

    // add all to content pane of dialog
    Container contentPane = getContentPane();
    contentPane.setLayout(new BorderLayout(5,5));
    contentPane.add(buttonPanel, BorderLayout.SOUTH);
  }

  /**
   * center a <code>Component</code> relative to
   * another <code>Component</code>.
   *
   * @param parent  the <code>Component</code> to be used as the
   *                  basis for centering
   * @param comp  the <code>Component</code> to be centered within parent
   *
   */
  public void center(Component parent, Component comp) {
    Dimension cSize = comp.getPreferredSize();
    Dimension fSize = parent.getSize();
    Point loc = parent.getLocation();
    comp.setLocation((fSize.width - cSize.width) / 2 + loc.x,
                            (fSize.height - cSize.height) / 2 + loc.y);
  }

  /**
   * dispose the dialog properly in case of window close events
   *
   * @param e  the event
   */
  protected void processWindowEvent(WindowEvent e) {
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      cancel();
    }
    super.processWindowEvent(e);
  }

  /**
   * cancel the operation
   */
  protected void cancel() {
    result = RESULT_CANCEL;
    dispose();
  }

  /**
   * confirm the operation
   */
  protected void confirm() {
    result = RESULT_OK;
    dispose();
  }

  /**
   * get the result of the operation performed in this dialog
   *
   * @return the result, one of RESULT_OK and RESULT_CANCEL
   */
  public int getResult() {
    return result;
  }

  /**
   * implements the ActionListener interface to be notified of
   * clicks onto the ok and cancel button.
   *
   * @param e  the ActionEvent that led to performance of this action
   */
  public void actionPerformed(ActionEvent e) {
    Object src = e.getSource();
    if(src == cancelButton) {
      cancel();
    }
    else if(src == okButton) {
      confirm();
    }
  }
  
}
